<?php

namespace app\common\util;

use app\common\exception\ServiceException;

/**
 * Created by PhpStorm.
 * User: zgh
 * Date: 2021-09-03
 * Time: 10:13
 */
class  RedisUtil
{
    protected $redis = null;

    protected static $_instance = null;


    protected static $EXPIRE_SECOND = 20; //默认就是20秒


    public static function getInstance()
    {
        if (!is_null(self::$_instance)) {
            return self::$_instance;
        }
        self::$_instance = new self();
        return self::$_instance;
    }

    public function __construct()
    {
        $connect_config = config("cache.redis");
        $redis = new \Redis();
        if (!empty($connect_config['timeout']) && $connect_config['timeout'] > 0) {
            $redis->connect($connect_config['host'], $connect_config['port'], $connect_config['timeout']);
        } else {
            $redis->connect($connect_config['host'], $connect_config['port']);
        }
        if (!empty($connect_config['password'])) {
            $redis->auth($connect_config['password']);
        }
        $this->redis = $redis;
    }


    public function __call($method, $args)
    {
        if (method_exists($this->redis, $method)) {
            return call_user_func_array(array($this->redis, $method), $args);
        } else {
            throw new ServiceException(__CLASS__ . ':' . $method . '不存在');
            return;
        }
    }

    /**
     *获取redis 资源操作脚柄
     */
    public function redisHandler()
    {
        return $this->redis;
    }

    /**
     * @param $lock_key
     * @param $lock_val
     * @param int $expire_time
     * @return bool
     */
    public function redisLock($lock_key, $lock_val, $expire_time = 0)
    {
        $redis = $this->redis;
        $expire_time || ($expire_time = self::$EXPIRE_SECOND);
        return $redis->set($lock_key, $lock_val, ['nx', 'ex' => $expire_time]);
    }

    /**
     * @param $lock_key
     * @param $lock_val
     * @return int [0,1]
     */
    public function redisLockDel($lock_key, $lock_val)
    {
        $redis = $this->redis;
        $lua = <<<LUA_SCRIPT
              local val = redis.call('get',KEYS[1]);
              if(val==ARGV[1]) then
                redis.call('del',KEYS[1]);
                return 1;
              end
                return 0;         
LUA_SCRIPT;
        return $redis->eval($lua, [$lock_key, $lock_val], 1);
    }


}